'''
Clase general de los planificadores(no abstracta) -> Subclases: PlanificadorFCFS, PlanificadorRR,
                                                    PlanificadorRRConPrioridad, PriorityPlanner
'''

import threading
from Signals.Kill import Kill

class Planificador:
    lock = threading.RLock()    
    #Metodo utilizado por el planificador FCFS que agrega un pid a la cola de ready
    def addTask(self, pid, kernel):
        self.lock.acquire()
        try:
            self.ready.append(pid)
        finally:
            self.lock.release()
    
    #Metodo utilizado por el planificador FCFS que retorna el proximo pid
    def returnNextPid(self, kernel):
        self.lock.acquire()
        try:
            if (len(self.ready) > 0):
                return self.ready.pop(0)
            else:
                kernel.interrupt(Kill())
        finally:
            self.lock.release()
    
    def reschedule(self, kernel):
        self.lock.acquire()
        try:
            #print('[kernel.sch] ready%s'%(self))
            #print('[kernel.sch] %s'%(kernel.memory))
            if kernel.CPU.pc is not None: # save pcb if necesary
                kernel.PCBT[kernel.current_pid] = kernel.CPU.pc
                self.addTask(kernel.current_pid, kernel)
                
            if len(self.ready) > 0:  # schedule next process
                kernel.current_pid = self.returnNextPid(kernel)
                kernel.CPU.pc = kernel.PCBT[kernel.current_pid]
                #print('[kernel.sch] scheduled pid %d'%(kernel.current_pid))
        finally:
            self.lock.release()
    
    def setQuantum(self, quantum):
        None
    
    def __repr__(self):
        return str(self.ready)
    
    def terminarProceso(self):
        pass
        
        
    
